package com.kaifamiao.wendao.dao;

import com.kaifamiao.wendao.entity.Customer;
import com.kaifamiao.wendao.entity.Topic;
import org.apache.commons.dbutils.ResultSetHandler;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.sql.*;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

public class TopicDao extends BaseDao<Topic,Long> {

    private static final String SELECT_MAX_ID = "SELECT max(id) FROM t_topics";
    private static final String INSERT = "INSERT INTO t_topics (title, content, publish_time, publish_address, priority, customer_id, id) VALUES (?,?,?,?,?,?,?)";
    private static final String UPDATE_ONE = "UPDATE t_topics SET title=?,content=?,publish_time=?,publish_address=?,priority=? WHERE id=?";
    private static final String SELECT_ONE = "SELECT id,title,content,customer_id,publish_time,publish_address,priority FROM t_topics WHERE id = ?";
    private static final String SELECT_ALL = "SELECT * FROM t_topics";
    private static final String DELETE_ONE = "DELETE FROM t_topics where id = ?";
    private static final String FETCH_BY_CUSTOMER_ID = "SELECT id, title, publish_time, priority, customer_id FROM t_topics WHERE customer_id = ? ORDER BY id DESC LIMIT ?,?";
    private static final String FETCH_BY_PAGE = "SELECT id, title,content, publish_time, priority, customer_id FROM t_topics ORDER BY id LIMIT ?,?";
    private static final String COUNT = "SELECT count(id) FROM t_topics";
    private static final String COUNT_BY_CUSTOMER = "SELECT count(id) FROM t_topics WHERE customer_id = ? ";

    @Override
    public boolean save(Topic t) {
        try {
            //获取发布地址
            InetAddress publishAddress = InetAddress.getLocalHost();
            //String hostName = publishAddress.getHostName();
            String hostAddress = publishAddress.getHostAddress();
            t.setPublishAddress(hostAddress);
            LocalDateTime datetime = t.getPublishTime();
            java.sql.Timestamp time = datetime != null ? java.sql.Timestamp.valueOf(datetime) : null ;
            // 获取发布者的标识符
            Long cid = t.getAuthor().getId();
            Object[] params = {t.getTitle(), t.getContent(), time, t.getPublishAddress(), t.getPriority(), cid, t.getId()};
            int count = runner.update(INSERT, params);
            return count == 1;
        }catch (SQLException | UnknownHostException cause){
            throw new RuntimeException("保存失败",cause);
        }
    }

    @Override
    public boolean update(Topic t) {

        Object[] param = {t.getTitle(),t.getContent(),t.getPublishTime(),t.getPublishAddress(),t.getPriority(),t.getId()};
        try {
            return runner.update(UPDATE_ONE,param) == 1;
        } catch (SQLException e) {
            throw new RuntimeException("更新失败",e);
        }

    }

    @Override
    public boolean remove(Long id) {

        try {
            return runner.update(DELETE_ONE,id) == 1;
        } catch (SQLException e) {
            throw new RuntimeException("删除失败",e);
        }
    }

    @Override
    public List<Topic> findAll() {
        ResultSetHandler<List<Topic>> rsHandler = rs -> {
            List<Topic> list = new ArrayList<>();
            while (rs.next()){
                Topic t = wrap(rs);
                list.add(t);
            }
            return list;

        };
        try {
            return runner.query(SELECT_ALL,rsHandler);
        } catch (SQLException e) {
            throw new RuntimeException("查询失败",e);
        }
    }

    @Override
    public Topic find(Long id) {
        try {
            return runner.query(SELECT_ONE, singleHandler, id);
        }catch (SQLException cause){
            throw new RuntimeException("查询失败",cause);
        }
    }
    private ResultSetHandler<Topic> singleHandler = rs -> {
        Topic t = null;
        if(rs.next()) {
            t = new Topic();
            t.setId(rs.getLong("id"));
            t.setTitle(rs.getString("title"));
            t.setContent(rs.getString("content"));
            java.sql.Timestamp time = rs.getTimestamp("publish_time");
            LocalDateTime publishTime = time != null ? time.toLocalDateTime() : null ;
            t.setPublishTime(publishTime);
            t.setPublishAddress(rs.getString("publish_address"));
            t.setPriority(rs.getInt("priority"));
            long cid = rs.getLong("customer_id");
            Customer author = new Customer();
            author.setId(cid);
            t.setAuthor(author);
        }
        return t;
    };

    public List<Topic> findByCustomerId(Long cid){
        ResultSetHandler<List<Topic>> rsHandler = rs -> {
            List<Topic> list = new ArrayList<>();
            while (rs.next()){
                Topic t = wrap(rs);
                list.add(t);
            }
            return list;

        };
        try {
            return runner.query(FETCH_BY_CUSTOMER_ID,rsHandler,cid);
        } catch (SQLException e) {
            throw new RuntimeException("查询失败",e);
        }
    }

    /**
     * 查询指定用户发布的所有话题
     * @param cid 带查询用户的编号
     * @return 返回指定用户发布的所有话题
     */
    public List<Topic> findByCustomerId(Long cid, int current, int size) {
        // 计算起始位置
        int begin = ( current - 1 ) * size ;
        try {
            return runner.query(FETCH_BY_CUSTOMER_ID, listHandler, cid, begin, size);
        }catch (SQLException cause){
            throw new RuntimeException("查询失败",cause);
        }
    }

    private Topic wrap(ResultSet rs) throws SQLException {
        Topic t = new Topic();
        t.setId(rs.getLong("id"));
        t.setTitle(rs.getString("title"));
        t.setContent(rs.getString("content"));

        java.sql.Timestamp ts = rs.getTimestamp("publish_time");
        LocalDateTime publish = ts == null ? null : ts.toLocalDateTime();
        t.setPublishTime(publish);

        t.setPublishAddress(rs.getString("publish_address"));
        t.setPriority(rs.getInt("priority"));

        long cid = rs.getLong("customer_id");
        Customer author = new Customer();
        author.setId(cid);
        t.setAuthor(author);

        return t;


    }

    // 统计话题数量
    public int count(){
        try {
            return runner.query(COUNT, rs -> rs.next() ? rs.getInt(1) : 0 );
        } catch (SQLException cause) {
            throw  new RuntimeException("统计失败",cause);
        }
    }

    // 统计指定用户的话题数量
    public int count(long customerId){
        try {
            return runner.query(COUNT_BY_CUSTOMER, rs -> rs.next() ? rs.getInt(1) : 0 , customerId);
        } catch (SQLException cause) {
            throw  new RuntimeException("统计失败",cause);
        }
    }

    // 分页查询
    public List<Topic> find(int current, int size) {
        // 计算起始位置
        int begin = ( current - 1 ) * size ;

        try {
            return runner.query(FETCH_BY_PAGE, listHandler, begin, size);
        }catch (SQLException cause){
            throw new RuntimeException("查询失败",cause);
        }
    }

    private ResultSetHandler<List<Topic>> listHandler = rs -> {
        List<Topic> list = new ArrayList<>();
        while (rs.next()) {
            Topic t = new Topic();
            t.setId(rs.getLong("id"));
            t.setTitle(rs.getString("title"));
            t.setContent(rs.getString("content"));
            java.sql.Timestamp time = rs.getTimestamp("publish_time");
            LocalDateTime publishTime = time != null ? time.toLocalDateTime() : null ;
            t.setPublishTime(publishTime);
            t.setPriority(rs.getInt("priority"));
            long cid = rs.getLong("customer_id");
            Customer author = new Customer();
            author.setId(cid);
            t.setAuthor(author);
            list.add(t);
        }
        return list;
    };


}
